package ru.exorg.core.service; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.rowset.SqlRowSet; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import java.sql.ResultSet; import ru.exorg.core.model.*; // ================================================================================ /** * Place of Interest Service * * poiIterator() method returns an object that iterates over all POIs * in the database. POI is incapsulated into an object * of type POI.Entry. * */ final public class POIProvider { private DataProvider dataProvider; private JdbcTemplate jdbc; private POIMapper poiMapper; private class POIMapper implements RowMapper<POI> { public POI mapRow(ResultSet rs, int rowNum) throws SQLException { POI poi = new POI(rs.getLong("id"), rs.getString("name")); poi.setCityId(rs.getLong("city_id")); poi.setURL(rs.getString("url")); poi.setAddress(rs.getString("address")); poi.setLocation(rs.getDouble("lat"), rs.getDouble("lng")); poi.setClusterId(rs.getLong("cluster_id")); poi.setClusterHeadFlag(rs.getBoolean("is_head")); poi.setSquareId(rs.getInt("sq_n")); poi.setType(rs.getLong("type_id")); SqlRowSet d_rs = jdbc.queryForRowSet("SELECT descr, src_url FROM poi_descr WHERE poi_id=?;", new Object[]{poi.getId()}); boolean v = d_rs.first(); while (v) { poi.addDescription(d_rs.getString("descr"), d_rs.getString("src_url")); v = d_rs.next(); } d_rs = jdbc.queryForRowSet("SELECT img_url FROM poi_image WHERE poi_id=?;", new Object[]{poi.getId()}); v = d_rs.first(); while (v) { poi.addImage(d_rs.getString("img_url")); v = d_rs.next(); } return poi; } } public POIProvider(DataProvider p) { this.dataProvider = p; this.jdbc = p.getJdbcTemplate(); this.poiMapper = new POIMapper(); } final public Iterator<POI> poiIterator() { return this.jdbc.query("SELECT * FROM place_of_interest;", new Object[]{}, poiMapper).iterator(); } final public List<POI> poiList() { return this.jdbc.query("SELECT * FROM place_of_interest;", new Object[]{}, poiMapper); } final public POI add(final String name) throws Exception { String q = String.format( "INSERT INTO place_of_interest(name) VALUES ('%s');", name ); this.dataProvider.getJdbcTemplate().execute(q); int newPoiId = this.dataProvider.getJdbcTemplate().queryForInt("SELECT LAST_INSERT_ID();"); return new POI(newPoiId, name); } final public void sync(final POI poi) throws Exception { jdbc.update( "UPDATE place_of_interest SET address=?, lat=?, lng=?, city_id=?, url=?, type_id=?, cluster_id=?, is_head=?, sq_n=? WHERE id=?;", poi.getLocation().getAddress(), poi.getLocation().getLat(), poi.getLocation().getLng(), poi.getCityId(), poi.getURL(), poi.getType(), poi.getClusterId(), poi.isClusterHead(), poi.getSquareId(), poi.getId()); jdbc.update("DELETE FROM poi_descr WHERE poi_id=?;", new Object[]{poi.getId()}); for (Description d : poi.getDescriptions()) { jdbc.update( "INSERT INTO poi_descr(poi_id, descr, src_url) VALUES (?, ?, ?);", poi.getId(), d.getText(), d.getSourceURL()); } jdbc.update("DELETE FROM poi_image WHERE poi_id=?;", poi.getId()); for (String img : poi.getImages()) { if (img.length() > 1) { jdbc.update( "INSERT INTO poi_image(poi_id, img_url) VALUES (?, ?);", poi.getId(), img); } } } final public List<String> getPOINames() { class POINamesMapper implements RowMapper<String> { public String mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getString("name"); } } return this.jdbc.query("SELECT name FROM place_of_interest;", new Object[]{}, new POINamesMapper()); } final public POI queryById(long id) { List<POI> r = this.jdbc.query("SELECT * FROM place_of_interest WHERE id = ?", new Object[]{id}, poiMapper); return r.get(0); } final public POI queryByName(final String name) { List<POI> r = this.jdbc.query("SELECT * FROM place_of_interest WHERE name = ? LIMIT 1", new Object[]{name}, poiMapper); return r.get(0); } final public List<POI> queryByAddress(final String address) { if (address != null) { return this.jdbc.query("SELECT * FROM place_of_interest WHERE address = ?", new Object[]{address}, poiMapper); } else { return null; } } final public List<POI> queryLike(final String name) { return this.jdbc.query("SELECT * FROM place_of_interest WHERE name LIKE ?", new Object[]{"%" + name.toLowerCase() + "%"}, poiMapper); } final public void removePOI(final POI poi) { this.jdbc.update("DELETE FROM place_of_interest WHERE id=?", poi.getId()); this.jdbc.update("DELETE FROM poi_descr WHERE poi_id=?", poi.getId()); this.jdbc.update("DELETE FROM poi_image WHERE poi_id=?", poi.getId()); } final private boolean hasDistance(final POI poi1, final POI poi2) { return this.jdbc.queryForInt("SELECT COUNT(*) FROM poi_distance WHERE poi_id1=? AND poi_id2=?;", poi1.getId(), poi2.getId()) > 0; } final public void setDistance(final POI poi1, final POI poi2, double distance) { if (poi1.getId() < poi2.getId()) { if (!hasDistance(poi1, poi2)) { this.jdbc.update("INSERT INTO poi_distance(poi_id1, poi_id2, distance) VALUES(?, ?, ?);", poi1.getId(), poi2.getId(), distance); } else { this.jdbc.update("UPDATE poi_distance SET distance=? WHERE poi_id1=? AND poi_id2=?;", distance, poi1.getId(), poi2.getId()); } } } } // ================================================================================